Newton Game Dynamics is a library for simulating dynamics of rigid bodies. It is being developed by Julio Jerez and Alain Suero and provides quick and accurate calculation for a large set of rigid objects.
With this wrapper you can easily use Newton Game Dynamics in your Blitz3D programs.
Primary features of physics simulation:
You must do the following steps before using the Newton wrapper in Blitz3D:
Each rigid body in simulation is described by following constants:
and variables:
Each body can be enabled or disabled. Disabled bodies are "turned off" and are not updated during simulation step. Disabling some bodies is a convinent way to reduce time of calculation if those bodies are known to be motionless or not strongly affect other bodies.
The process of simulating the rigid body system through time is called integration. Each integration step advances the current time by a given step size, adjusting the state of all the rigid bodies for the new time value.
Between each integrator step the user can call functions to apply forces to the rigid body. These forces are added to ”force accumulators” in the rigid body object. When the next integrator step happens, the sum of all the applied forces will be used to push the body around. The forces accumulators are set to zero after each integrator step.
Joint is a relationship that is enforced between two bodies so that they can only have certain positions and orientations relative to each other. This relationship is called a constraint – the words joint and constraint are often used interchangeably.
When a joint attaches two bodies, those bodies are required to have certain positions and orientations relative to each other. However, it is possible for the bodies to be in positions where the joint constraints are not met. This “joint error” can happen in two ways:
There is a mechanism to reduce joint error: during each simulation step each joint applies a special force to bring its bodies back into correct alignment. This force is controlled by the error reduction parameter (Stiffness), which has a value between 0 and 1.
The Stiffness specifies what proportion of the joint error will be fixed during the next simulation step. If Stiffness=0 then no correcting force is applied and the bodies will eventually drift apart as the simulation proceeds. If Stiffness=1 then the simulation will attempt to fix all joint error during the next time step. However, setting Stiffness=1 is not recommended, as the joint error will not be completely fixed due to various internal approximations. A value of Stiffness=0.1 to 0.8 is recommended (0.2 is the default).
To make simulation more realistic each body has a material, assigned to it. The collision parameters (like friction coefficient or softness) are set for materials (for example, elasticity in collision between rubber and ground). And materials are set for bodies (for example, wheels made of rubber or box made of wood).
Physics world is a container for all bodies, materials and joints involved in simulation. There can be only one world.
Create a new world. This function has to be called before any other physics function. If "plane%" parameter is set to True, a horizontal plane will be created at point (0,0,0). "License_key$" is your license key. Key is sensitive to symbol case. If license key is not correct, phWorlsStep is limited to 2000 calls.
Set the world size. Bodies outside the box (x1#,y1#,z1#)-(x2#,y2#,z2#) will not be updated. Default values - from (-10000.0,-10000.0,-10000.0) to (10000.0,10000.0,10000.0). It is not recommended to set unnecessary huge values, otherwise it may cause an increase of the calculation time.
Set the gravity in the world. Default values - (0, -9.81, 0). During simulation step all bodies are affected with gravity force equal to gravity multiplied by body mass.
Step the world. This function advances the simulation by the amount of time specified by timestep. Timestep must be within limits 1/60.0 (=0.01666) - 1/600.0 (=0.0016666) otherwise it will be clamped.
Destroy the world, all bodies, materials and joints.
Create a new material and return its index.
Set the default collision parameters for new materials (see below).
Set the collision parameters for specified materials. mat1% and mat2% are indices of materials.
Create a body with no geometry (and therefore non-collidable) with specified mass. Return handler of the created body.
Create a box with dimensions (dx#,dy#,dz#) and specified mass. Return handler of created body.
Create a ellipsoid with semiaxis (rx#,ry#,rz# ) and specified mass. Return handler of the created body.
Create a cylinder with radius r#, height h# and specified mass. Return handler of created body.
Create cone with radius of base r#, height h# and specified mass. Return handler of the created body.
Create capsule with radius of base r#, height h# and specified mass. Return handler of the created body.
Destroy the body and delete it from the world.
Create a body with any convex geometry determined by user. Convex geometry is determined by a set of vertices in bank Vertices*{x0,y0,z0,x1,y1,z1,x2,y2,z2,...}. VertexCount% is amount of vertices in bank, mass# is the mass of body. The body's centre of mass and inertia momentums are calculated by the wrapper automatically.
These functions are used to create body with geometry compounded of set of convex geometries. So the result geometry can be non-convex.
First, function phBodyCompoundBegin() has to be called. It starts building of the body.
Function phBodyCompoundAddHull(Vertices*, VertexCount%) adds a convex geometry to the body. Parameters Vertices* and VertexCount% are similar to parameters of phBodyCreateHull.
Function phBodyCompoundAddBody(body%) copies a convex geometry from specified body% to the body which is being built.
Function phBodyCompoundEnd finishes building of body, sets mass for body and calculates the center of mass and intertia momentums. It returns handler of the created body.
These functions are used to create compound body too. But you can set mass for each part of your compound body. Result mass and inertia momentums will be calculated by wrapper.
phBodyCompoundExBegin() - start building.
phBodyCompoundExAddHull(Vertices*, VertexCount%, mass#) - add hull with mass mass# to the compound body.
phBodyCompoundExAddHullDens(Vertices*, VertexCount%, density#) - add hull with density# to the compound body.
phBodyCompoundExAddBody(body%) - copy geometry from specified body to the compound. Mass of this part will be equal to the body's mass.
phBodyCompoundExEnd%() - finish body building and return handler of the created body.
Assign material with index mat% to specified body.
Return material index of specified body.
X,Y,Z coordinates and Pitch,Yaw,Roll angles determine position and orientation of body in world space. When a new body creates these values are zeroed.
Functions return coordinates of specified body.
Set the coordinates of body.
Return angles of specified body.
Set angles of body.
Return linear velocity of body.
Set linear velocity of body.
Return angular velocity (omega) of body.
Set angular velocity (omega) of body.
Simulation should be operated only by applying forces and torques to bodies. Try to set position and orientation of body only when create or reset it.
Add force (fx,fy,fz) at the body's centre of mass. Values (fx,fy,fz) are in global space.
Add force (fx,fy,fz) at the body's centre of mass. Values (fx,fy,fz) are in local (body-relative) space.
Add force (fx,fy,fz) to body at point (x,y,z). All values are in global space.
Add force (fx,fy,fz) to body at point (x,y,z). All values are in local (body-relative) space.
Add impulse to body at point (x,y,z). (vx,vy,vz) is change of velocity at point (x,y,z) . Values x,y,z and vx,vy,vz are in global space. This function is equivalent to phBodyAddForceAtPos(body,x,y,z,vx*mass/timestep,vy*mass/timestep,vz*mass/timestep), where mass# is mass of body, timestep# - current step of simulation.
Add torque to body. Torque values tx,ty,tz are in global space.
Add torque to body. Torque values tx,ty,tz are in local (body-relative) space.
When a body is created, center of mass and inertia momentums are calculated automatically by the wrapper.
the following functions allow user to set mass, inertia momentum and centre of mass manually.
Set mass of body. Inertia momentums are changed proportionally ( i.e. momentum/mass is constant)
Set mass and inertia momentums of body. Inertia momentums are in local (body-relative) space.
Return mass and inertia momentum of body.
Set position of body's mass centre. Coordinates x,y,z are in local (body-relative) space.
Return coordinates of body's mass centre in local (body-relative) space.
Return body's volume.
Following functions allow user to enable and disable bodies.
Set body's sleeping state. If sleep% = 1, body will sleep (disabling), if sleep% = 0, body will wake up (enabling).
Return sleeping state of body. If it returns 1 body is disabled (sleep), if it returns 0 body is enabled (not sleep).
Newton Game Dynamics engine can disable bodies automatically if they are at rest. If state% = True, engine is allowed to disable specified body, otherwise not.
Set parameters for body's auto-sleep. Body will be disabled if its linear velocity is lower than vel# and angular velocity is lower than omega# for frames% simulation steps.
All collisions for all bodies are available to user after each simulation step. All following functions return coordinates in global space.
Return amount of contacts for specified body.
Return handler of body which is collided with specified body at contact indexed coll%
Return 0 if bodies body1% and body2% are not coliided, otherwise return (contact index + 1). Contact index is correct for body1.
Return coordinates of contact with index coll%.
Return components of normal of contact with index coll%.
Return components of force at point of contact with index coll%.
Return normal, tangent and binormal components of contact velocity. Contact velocity depends on relative speeds of collided bodies.
Return velocity of specified point of a body. Coordinates (x,y,z) of a point are in global space.
Set and return gravity mode for specified body. If mode% = 1, the body will be affected by the force of gravity, otherwise not.
Set the fluid plane for specified body. If fluid plane is set, the buyoance force will be calculated and automatically applied to body.
Disable calculation and applying of buyoance force for specified body.
Set coefficients of linear and angular viscous damping (in air) for specified body.
Set and return continuous collision mode for specified body. If mode% = True, continuous collision is enabled, otherwise not. Enabling continuous collision allow the engine to predict colliding contact on rigid bodies moving at high speed of subject to strong forces. Because there is a penalty of about 40%-80% depending on the shape complexity of the collision geometry, this feature is switched off by default. It is the a job of the application to determine which body needs this feature on. Good guidelines are: very small objects, and bodies that move at a height speed.
Set and return any user data for body.
Set and return entity handler for specified body. If entity is set, it will be automatically positioned and rotated just as corresponded body.
Any body is considered as static if its mass is zero.
There are two additional ways to create static body with complex geometry.
Level is a static body with geometry represented as an arbitrary set of triangles. Like compound bodies, level is created in three steps.
Start level build.
Add triangle to level geometry. x1#,y1#,z1#,x2#,y2#,z2#,x3#,y3#,z3# - coordinates of trinagle vertices.
Finish level build and return handler of the created body.
Create body with geometry represented as a height field. Return handle of the created body.
Note: The coordinates and directions of all joints are set and returned in the global space.
Note: If you create joint between two bodies, first body (body1%) must be non-static, second body (body2%) can be static or null. If body2% is null, body1% will be jointed to global static environment.
Create ball joint at position (x#,y#,z#) between body1% and body2. Return handler of the created joint.
Set ball-joint limits for specified joint%. First limit is the limit of the cone angle between jointed bodies. It is desribed by the direction of the cone axis (nx#,ny#,nz#) and the value of the cone angle (coneAngle#). Second limit is the limit of twist angle between jointed bodies (twistAngle#). If cone or twist limit is set to zero, the limit will be disabled.
Return the force applied by joint% to maintain the constraint.
Create hinge-joint at position (x#,y#,z#) and direction (nx#,ny#,nz#) between body1% and body2%. Return handler of the created joint.
Set the limit of the relative angle between bodies connected by joint%. Relative angle will be limited within (min#,max#).
Return the relative angle between bodies connected by joint%.
Return the relative angular velocity (omega) between bodies connected by joint%.
Return the force applied by joint% to maintain the constraint.
Create slider-joint at position (x#,y#,z#) and direction (nx#,ny#,nz#) between body1% and body2%. Return handle of created joint.
Set the limit of relative displacement of bodies connected by joint%. The difference between current distance and initial distance between bodies will be within (min#,max#). For example, the limits of (-1.0, 1.0) mean that the bodies can approach to each other less than 1.0 meter. And they can move away from each other less then 1.0.
Return the relative displacement of bodies connected by joint%.
Return the relative velocity of bodies connected by joint% along joint's axis.
Return the force applied by joint% to maintain the constraint.
Cork joint is similar to hinge and slider joints. Bodies connected by such joint can move along the axis and rotate around it. And all functions of cork joint are similar to corresponded fucntions of hinge joint or slider joint.
An up vector joint is a constraint that allows a body to translate freely in 3d space, but it only allows the body to rotate around the pin direction vector. This could be use by the application to control a character with physics and collision.
Create up vector joint with pin axis (nx#,ny#,nz#) and attach it to the specified body%.
Reorient pin axis of joint% to the direction (nx#,ny#,nz#).
Return the current direction of joint pin.
Universal joint is similar to two linked hinge joints. Bodies connected by universal joint can rotate around first axis and around second axis, but can't rotate around vector that is perpendicular to joint axes.
Create universal joint between body1% and body2% at point(x#,y#,z#) and directions (nx1#,ny1#,nz1#),(nx2#,ny2#,nz2#). Return the handle of created joint.